package com.icexxx.lathe;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IceSessionUtil {

    public static String sessionId() {
        String securityContextHolderClassName = "org.springframework.security.core.context.SecurityContextHolder";
        Class<?> securityContextHolderClass = null;
        String username = null;
        try {
            securityContextHolderClass = Class.forName(securityContextHolderClassName);
            Method SecurityContextHolderMethod = securityContextHolderClass.getDeclaredMethod("getContext");
            SecurityContextHolderMethod.setAccessible(true);
            Object context = SecurityContextHolderMethod.invoke(null, new Object[] {});
            String SecurityContextClassName = "org.springframework.security.core.context.SecurityContext";
            Class<?> securityContextClass = Class.forName(SecurityContextClassName);
            Method authenticationMethod = securityContextClass.getDeclaredMethod("getAuthentication");
            authenticationMethod.setAccessible(true);
            Object authenticationObj = authenticationMethod.invoke(context, new Object[] {});
            String authenticationClassName = "org.springframework.security.core.context.Authentication";
            Class<?> authenticationClass = Class.forName(authenticationClassName);
            Method principalMethod = authenticationClass.getDeclaredMethod("getPrincipal");
            principalMethod.setAccessible(true);
            Object principalMethodObj = principalMethod.invoke(authenticationObj, new Object[] {});
            String userDetailsClassName = "org.springframework.security.core.userdetails.UserDetails";
            Class<?> userDetailsClass = Class.forName(userDetailsClassName);
            boolean assignableFrom = userDetailsClass.isInstance(principalMethodObj);
            if (assignableFrom) {
                Object principal = userDetailsClass.cast(principalMethodObj);
                Method usernameMethod = userDetailsClass.getDeclaredMethod("getUsername");
                usernameMethod.setAccessible(true);
                Object usernameObj = usernameMethod.invoke(principal, new Object[] {});
                username = usernameObj.toString();
            } else {
                username = principalMethodObj.toString();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        }
        return username;
    }

}
